﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace SFast
{
    public static class StringExtensions
    {
        #region String 扩展函数   _HtmlToString（）  HTML特殊符号转义
        /// <summary>
        /// HTML 特殊符号 转义
        /// </summary>
        /// <param name="str">字符串实体</param>
        /// <returns></returns>
        public static String _HtmlToString(this string str)
        {
            return HttpContext.Current.Server.HtmlEncode(str);
        }
        #endregion

        #region String 扩展函数：   _RemoveHtml()    //删除字符串的html标签
        /// <summary>
        /// 删除字符串的html标签
        /// </summary>
        /// <param name="Htmlstring">删除字符串后的纯文本</param>
        /// <returns></returns>
        public static String _RemoveHtml(this string Htmlstring)
        {
            //删除脚本  
            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
            //删除HTML  
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);

            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);

            Htmlstring.Replace("<", "");
            Htmlstring.Replace(">", "");
            Htmlstring.Replace("\r\n", "");
            Htmlstring = HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();

            return Htmlstring;
        }
        #endregion

        #region String 扩展函数：   _Substring    //截取字符串

        /// <summary>
        /// 截取字符串长度 
        /// </summary>
        /// <param name="str">字符串实例</param>
        /// <param name="length">要截取的长度</param>
        /// <param name="AddStr">当字符串实例长度大于需要的长度时，所要追加的字符串</param>
        /// <returns>返回截取后字符串</returns>
        public static String _Substring(this string str, int length, String AddStr)
        {
            Regex regex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);
            char[] stringChar = str.ToCharArray();
            StringBuilder sb = new StringBuilder();
            int nLength = 0;
            for (int i = 0; i < stringChar.Length; i++)
            {
                if (regex.IsMatch((stringChar[i]).ToString()))
                {
                    sb.Append(stringChar[i]);
                    nLength += 2;
                }
                else
                {
                    sb.Append(stringChar[i]);
                    nLength = nLength + 1;
                }

                if (nLength >= length)
                {
                    break;
                }
            }

            var strLength = System.Text.Encoding.Default.GetBytes(str).Length;
            if (length < strLength)
            {
                sb = sb.Append(AddStr);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 截取字符串长度。子字符串从指定的字符位置开始且具有指定的长度。（
        /// (length值大于字符串长度时，从起点截取到最后位置）
        /// </summary>
        /// <param name="str">字符串实例</param>
        /// <param name="startIndex">坐标开始位置</param>
        /// <param name="length">要截取的长度</param>
        /// <returns>返回截取后字符串</returns>
        public static String _Substring(this string str, int startIndex, int length)
        {
            str = str.Substring(startIndex);
            str = str._Substring(length, "");
            return str;
        }


        /// <summary>
        /// 截取字符串长度。子字符串从指定的字符位置开始且具有指定的长度。（
        /// (length值大于字符串长度时，从起点截取到最后位置）
        /// </summary>
        /// <param name="str">字符串实例</param>
        /// <param name="startIndex">坐标开始位置</param>
        /// <param name="length">要截取的长度</param>
        /// <param name="AddStr">当字符串实例长度大于需要的长度时，所要追加的字符串</param>
        /// <returns>返回截取后字符串</returns>
        public static String _Substring(this string str, int startIndex, int length, string AddStr)
        {
            var strLength = System.Text.Encoding.Default.GetBytes(str).Length;
            str = str.Substring(startIndex);
            return str._Substring(length, AddStr);
        }
        #endregion

        #region String 扩展函数：   _Replace    //字符串替换，可以不区分大小写
        /// <summary>
        /// 字符串替换，可以不区分大小写
        /// </summary>
        /// <param name="str">字符串实例</param>
        /// <param name="OldValue">要替换的字符串</param>
        /// <param name="NewValue">要替换OldValue 相匹配的字符串</param>
        /// <param name="StringType">System.StringComparison 值之一</param>
        /// <returns>返回替换好的字符串</returns>
        public static String _Replace(this string str, string OldValue, string NewValue, StringComparison StringType)
        {
            string NewStr = str;
            int index = -1;
            do
            {
                index = str.IndexOf(OldValue, StringType); //获取旧字符串在源字符中的坐标
                if (index != -1)
                {
                    String oldstr = str.Substring(index, OldValue.Length);  //通过坐标获取相对应的字符串
                    NewStr = NewStr.Replace(oldstr, NewValue);    //把新字符串中的数据替换为想要的字符串
                    str = str.Replace(oldstr, "");
                }
                index = str.IndexOf(OldValue, StringType); //获取旧字符串在源字符中的坐标
            } while (index != -1);

            return NewStr;
        }
        #endregion

        #region String 扩展函数：   _Replace    //字符串替换，可以不区分大小写,可以嵌套替换如“MmccmM”替换为“<sapn>Mm</span>cc<sapn>mM</span>”
        /// <summary>
        /// 字符串替换，可以不区分大小写,可以嵌套替换如“MmccmM”替换为“<sapn>Mm</span>cc<sapn>mM</span>”
        /// </summary>
        /// <param name="str">字符串实例</param>
        /// <param name="OldValue">要替换的字符串</param>
        /// <param name="NewValue">要替换OldValue 相匹配的字符串可以是</param>
        /// <param name="StringType">System.StringComparison 值之一</param>
        /// <param name="bo">是否使用 <sapn>{0}</span> 的方式替换</param>
        /// <returns>返回替换好的字符串</returns>
        public static String _Replace(this string str, string OldValue, string NewValue, StringComparison StringType, bool bo)
        {
            string NewStr = String.Empty;
            int index = -1;
            do
            {
                index = str.IndexOf(OldValue, StringType); //获取旧字符串在源字符中的坐标
                if (index != -1)
                {
                    String oldstr = str.Substring(index, OldValue.Length);  //通过坐标获取相对应的字符串
                    if (bo)
                    {
                        NewStr += str.Substring(0, index);
                        NewStr += string.Format(NewValue, oldstr);    //把新字符串中的数据替换为想要的字符串
                        str = str.Substring(index + oldstr.Length);  //去掉要替换的字符串
                        index = str.IndexOf(OldValue, StringType);
                    }
                    else
                    {
                        NewStr = NewStr.Replace(oldstr, NewValue);    //把新字符串中的数据替换为想要的字符串
                    }
                }

                if (index == -1 && str.Length > 0)
                {
                    NewStr += str.Substring(0);
                }
                index = str.IndexOf(OldValue, StringType); //获取旧字符串在源字符中的坐标
            } while (index != -1);

            return NewStr;
        }
        #endregion

        #region 将16进制转换成byte[]类型 、16进制转换成2进制 、字符串转16进制字节
        /// <summary>
        /// 将16进制转换成byte[]类型
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public static byte[] _HexToBytes(this String hexStr)
        {
            if (hexStr == null)
            {
                throw new NullReferenceException("参数hexStr不可以为null!");
            }
            List<byte> list = new List<byte>();
            try
            {
                for (int i = 0; i < hexStr.Length / 2; i++)//逐字节变为16进制字符，以%隔开
                {
                    var str = Convert.ToByte(Convert.ToInt32(hexStr.Substring(i * 2, 2), 16));
                    list.Add(str);
                }
                return list.ToArray();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 16进制转换成2进制，默认utf-8
        /// </summary>
        /// <param name="hexStr">16进制字符串</param>
        /// <returns></returns>
        public static String _HexToBinary(this String hexStr)
        {
            return _HexToBinary(hexStr, Encoding.UTF8);
        }

        /// <summary>
        /// 16进制转换成2进制
        /// </summary>
        /// <param name="hexStr">16进制字符串</param>
        /// <param name="encode">编码格式</param>
        /// <returns></returns>
        public static String _HexToBinary(this String hexStr, Encoding encode)
        {
            if (hexStr == null)
            {
                throw new NullReferenceException("参数hexStr不可以为null!");
            }
            List<byte> list = new List<byte>();
            try
            {
                for (int i = 0; i < hexStr.Length / 2; i++)//逐字节变为16进制字符，以%隔开
                {
                    var str = Convert.ToByte(Convert.ToInt32(hexStr.Substring(i * 2, 2), 16));
                    list.Add(str);
                }
                return encode.GetString(list.ToArray());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary> 
        /// 字符串转16进制字节数组 
        /// </summary> 
        /// <param name="hexString"></param> 
        /// <returns></returns> 
        public static byte[] _ToHexByte(this String hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
            {
                hexString += " ";
            }
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
            {
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            }
            return returnBytes;
        }
        #endregion
    }
}
